package Day_0216.JVM.GarbageCollection;

/**
 * @author zxc
 * @date 2023/02/16 17:54
 **/
public class Methodarea_Heap_Difference {
    public static void main(String[] args) {
        /**
         * 方法区和堆之间的区别
         * ===》
         * 1.逻辑上，方法区是属于堆的一部分，但实现上，一些简单的jvm实现，可能不会对方法区选择进行垃圾收集或者进行压缩。
         * HotSpot虚拟机的方法区，还有一个别名，叫做 Non-Heap（非堆），目的就是要和堆分开。
         * ===》所以，方法区被看作是，一块独立于Java堆的内存空间 。
         * （1）方法区，是各线程共享的内存区域。
         * （2）方法区在JVM启动时被创建，其实例的物理内存空间可以是不连续的。
         * （3）方法区的大小，可以选择固定大小或者可扩展。
         *  如果方法区无法满足新的内存分配需求时，将抛出OOM异常。
         * （4）方法区的大小决定了系统可以保存多少个类，如果系统定义了太多的类，会导致方法区溢出，虚拟机会抛出内存溢出错误：
         *  java.lang.OutOfMemoryError: PermGen space
         *  java.lang.OutOfMemoryError: Metaspace
         *
         * 2.方法区溢出的所有可能情况：
         * （1）加载大量的第三方的jar包；
         * （2）Tomcat部署的工程过多（30-50个）；
         * （3）大量动态地生成反射类。
         * ===》关闭JVM，就会释放该区域的内存。
         *
         * 3.方法区是虚拟机规范中提出的，不同的虚拟机可以有不同的实现，
         * 在HotSpot不同版本中方法区的演进如下：
         * （1）在JDK7及以前，习惯上把方法区称为 永久代（PermGen）;从JDK8开始，使用 元空间（Metaspace） 作为方法区的实现。
         *
         * （2）本质上，方法区和永久代并不等价，这两个概念仅是对 hotspot而言的。
         *  现在来看，当年使用永久代，不是好的idea，导致Java程序更容易出现OOM（超过-XX:MaxPermsize上限）。
         *  元空间的本质和永久代类似，都是对JVM规范中方法区的实现。
         * ===》
         * 两者的最大区别是：元空间不在虚拟机设置的内存中，而是使用本地内存。
         *
         */
    }
}
